package com.zeus.core.report;

import com.zeus.common.enums.ZeusEventTypeEnum;
import com.zeus.common.utils.StackTraceUtils;
import com.zeus.core.open.api.annotation.ZeusAlarmAop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;

/**
 * 注解上报工具
 *
 * @author f1ybear_wang  2022/2/25 10:42 上午
 */
public class ZeusReportAnnotationClient extends AbstractOpenApiZeusReportClient {
    /**
     * 切面
     */
    protected ProceedingJoinPoint point;
    /**
     * 注解信息
     */
    protected ZeusAlarmAop alarm;
    /**
     * 异常
     */
    protected Throwable throwable;

    public ZeusReportAnnotationClient(ProceedingJoinPoint point, ZeusAlarmAop alarm, Throwable throwable) {
        super();
        this.point = point;
        this.alarm = alarm;
        this.throwable = throwable;
    }

    @Override
    public ZeusEventTypeEnum eventType() {
        return ZeusEventTypeEnum.ANNOTATION_EVENT;
    }

    @Override
    protected void parsingExtend() {
        if (this.alarm != null) {
            this.gatherRule.setAlarmLevel(this.alarm.level());
            this.message = this.alarm.message();
            this.solution = this.alarm.solution();

            this.parsingExtendInit = true;
        }
        if (this.point != null) {
            // 获取类名
            String classType = point.getTarget().getClass().getName();
            try {
                Class<?> clazz = Class.forName(classType);
                this.className = clazz.getName();
            } catch (Exception ignored) {
            }
            final Signature signature = point.getSignature();
            if (signature != null) {
                this.methodName = signature.getName();
                this.argNames = ((MethodSignature)signature).getParameterNames();
            }
            this.args = point.getArgs();

            try {
                // 获取行信息
                Integer lineNumber = point.getSourceLocation() == null ? null : point.getSourceLocation().getLine();
                this.lineNumber = lineNumber == null ? null : lineNumber.toString();
            } catch (UnsupportedOperationException ignored) {
                // MethodInvocationProceedingJoinPoint .getLine()会抛异常
            }
        }

        if (throwable != null) {
            this.exceptionMessage = throwable.getMessage();
            this.stackTrace = StackTraceUtils.getStackTrace(throwable);

            // 获取行信息
            StackTraceElement[] stackTrace = throwable.getStackTrace();
            if (stackTrace != null && stackTrace.length > 0) {
                for (StackTraceElement element : stackTrace) {
                    if (element.getClassName().equals(this.className)) {
                        this.fileName = element.getFileName();
                        this.lineNumber = String.valueOf(element.getLineNumber());
                        break;
                    }
                }
            }
        }
    }

}
